/*
*********************************
	  SF2D Engine
*********************************

	By Julian Williams
	September 30, 2010
**********************************

	Description:

		Creep type derived from the
	Entity class
***********************************
*/
#include <iostream>
using namespace std;


#include "physics_world.h"
#include "path_finder.h"
#include "script_engine.h"
#include "levels.h"
#include "cfg_reader.h"
#include "image_manager.h"

#include "creep.h"

//a private copy function so that i don't have to
//copy/paste the copy constructor to the
//equal operator
void Creep::copyEntity(const Entity *e)
{
	
	Creep *e_copy = (Creep*)e;
	Entity::copyEntity(e);

	health = e_copy->health;
	img = e->img;
}//EoF


Creep::Creep()
{
	refCount = 1;
	cout << "Called lol?" << endl;
}//EoF


//Copy Constructor
Creep::Creep(const Entity &other)
{
	
	copyEntity(&other);

	//PrepareSpawn(Map.pathStart);

}//EoF



//Register sheeit
bool Creep::Register_With_ScriptEngine()
{
	//Register Properties
		int r = aScriptEngine.GetEngine()->RegisterObjectProperty("Entity", "PathComponent pathComponent",	offsetof(Creep, pathComponent));		assert( r >= 0 );
		if(r < 0) { return false; }

		return true;
}//EoF



//Prepare Spawn
void Creep::PrepareSpawn(const b2Vec2 &start)
{
	cout << "Before: " <<  start.x << ", " << start.y << endl;

	Entity::PrepareSpawn(start);

	//Physics things
	bodyDef.position = METERS_PER_PIXEL * start;
	body = physicsManager.world->CreateBody( &bodyDef );
	fixtureDef.shape = &circleDef;
	body->CreateFixture( &fixtureDef  );


	body->SetUserData((void*)(this));



	b2Vec2 end(Map.pathEnd);

	cout << start.x << ", " << start.y << endl;
	int result = -1;
	result = pathComponent.FindPath(start, end);

	if(result == MicroPather::NO_SOLUTION)
	{
		MarkRemoval();
		cout << "working? " << result << endl;
	}
	SetImage(*img);
}//EoF


//Update logical actions of the creep' using standard entity stuff
void Creep::Update_Logic(asIScriptContext *context)
{
	Entity::Update_Logic(context);

	if(health <= 0)
	{
		MarkRemoval();
	}

}//EoF




void Creep::OnCollision(const Entity *other_body)
{
	//Entity* ob = (Entity*)other_body->GetUserData();
	if(other_body->type == ET_PROJECTILE)
	{
		health -= other_body->damage;
	}
}//EoF

//Render to framebuffer, standard draw of self
void Creep::Render(sf::RenderWindow * rendow)
{			
	Entity::Render(rendow);
}//EoF





/* Get the Configuration file and load properties */
bool Creep::Get_Config(const string& resource_dir)
{

	
	//grab and create the nessisary directories
	string image_location = resource_dir + string("image.png");
	string cfg_location = resource_dir + string("properties.cfg");
	//string script_name = App::getInstance().Resources_Dir["scripts"];
	//string snd_location = folder_location + string("fire.wav");

	cout << "Loading Entity folder: " << resource_dir << endl;
	cout << "Config from: " << cfg_location << endl;
	cout << "Image from: " << image_location << endl;

	//cout << "Gun sound from: " << snd_location << endl;



//Now Grab the firing sound for the gun
	//if(!Load_Sounds(s_fire, SND_fire, snd_location)) { return false; }




//Grab particle Config
		cfg_reader cfg(cfg_location, true);


//Get all of the properties
			type = cfg.Get_Info("info:type", 1);
			name = cfg.Get_Info("info:name", "Default");
			
			damage = cfg.Get_Info("info:damage", 10);
			speed = cfg.Get_Info("info:speed", 100);
			health = cfg.Get_Info("info:health", 100);

		//	script_name += cfg.Get_Info("info:script_driver", "NULL");


//Animation related information
			tile_size.x = cfg.Get_Info("animation:tile_width", 32);
			tile_size.y = cfg.Get_Info("animation:tile_height", 32);

			sf::Vector2f origin;
			origin.x = cfg.Get_Info("animation:origin_x",16);
			origin.y = cfg.Get_Info("animation:origin_y",16);
			SetOrigin( origin );
		
			//cout << "Particle Image from: " << image_location << "\n\n";

			//Load Particle Image used for each type
			img = gImageManager.getResource( image_location );
			if(img == NULL) { return false; }
			SetImage( *img );


//Setup Physics
//create the dynamic body
			bodyDef.type = static_cast<b2BodyType> (cfg.Get_Info("physics:body_type", b2_dynamicBody));
			bodyDef.linearDamping = cfg.Get_Info("physics:linear_damping", 20);
			bodyDef.fixedRotation = cfg.Get_Info("physics:fixed_rotation", false);
			bodyDef.bullet = cfg.Get_Info("physics:continues_collision", false);

			//shape of the dynamic body
			//shapeDef.SetAsBox(tile_size.x/2*METERS_PER_PIXEL, tile_size.y/2*METERS_PER_PIXEL);
			
			//circle.m_p.Set(50*MPP, 50*MPP);
			circleDef.m_radius = cfg.Get_Info("physics:radius", 16) * METERS_PER_PIXEL;
		
		

			fixtureDef.shape		= &circleDef;
			
			fixtureDef.filter.categoryBits = 0x0004;

			fixtureDef.density		= cfg.Get_Info("physics:density", 1.0);
			fixtureDef.friction		= cfg.Get_Info("physics:friction", 0.3); 
			fixtureDef.restitution	= cfg.Get_Info("physics:bounciness", 0.5);
			fixtureDef.isSensor		= cfg.Get_Info("physics:is_sensor", false);

			//apply the fixture to the body
			//body->CreateFixture(&fixtureDef);

	return true;
}//EoF
